package kuzha.runtime;

import java.util.AbstractList;
import java.util.Iterator;
import java.util.ListIterator;

import kuzha.KuzhaObject;

public class RangeList extends AbstractList<KuzhaObject> implements CustomList {
	public final int start;
	public final int end;
	public final int step;
	public final int size;
	
	public RangeList(int start, int step) {
		this.start = start;
		this.end = 0;
		this.step = step;
		this.size = -1;
	}
	public RangeList(int start, int end, int step) {
		this.start = start;
		this.end = end;
		this.step = step = start <= end ? Math.abs(step) : -Math.abs(step);
		this.size = end == start ? 1 : (end - start) / step + 1;
	}
	
	public boolean isInfiniteList() {
		return size < 0;
	}
	
	private int get_internal(int i) {
		return start + step * i;
	}
	
	@Override
	public KuzhaObject get(int index) {
		if (isInfiniteList() || 0 <= index && index < size)
			return KzInt32.valueOf(get_internal(index));
		throw new IndexOutOfBoundsException("KzRangeList out of range: " + index);
	}

	@Override
	public int size() {
		return isInfiniteList() ? Integer.MAX_VALUE : size;
	}
	
	@Override
	public String toString() {
		if (isInfiniteList())
			return "[" + start + ".." + (step != 1 ? ";" + step + "]" : "]");
		else
			return "[" + start + ".." + end + (step != 1 ? ";" + step + "]" : "]");
	}
	
	@Override
	public KzList slice(int start) {
		int start_value = get_internal(start);
		if (isInfiniteList())
			return KzList.newList(new RangeList(start_value, this.step));
		else
			return KzList.newList(new RangeList(start_value, this.end, this.step));
	}
	@Override
	public KzList slice(int start, int end) {
		if (end < start)
			throw new IllegalArgumentException("");
		int start_value = get_internal(start);
		int end_value = get_internal(end);
		return KzList.newList(new RangeList(start_value, end_value, this.step));
	}
	@Override
	public Iterator<KuzhaObject> iterator() {
		return new RangeListIterator(this);
	}
	@Override
	public ListIterator<KuzhaObject> listIterator() {
		return new RangeListIterator(this);
	}
	@Override
	public ListIterator<KuzhaObject> listIterator(int arg0) {
		return new RangeListIterator(this, arg0);
	}
}
